

package jetbrains.buildServer.server.rest.util;

import java.util.function.Supplier;
import org.jetbrains.annotations.NotNull;

/**
 * Calculates value once on the first access and saves in cache. Then returns cached value.
 *
 * @author Yegor.Yarko
 * @since 24.01.14
 */
public abstract class CachingValue<S> {
  private S myValue;

  @NotNull
  final public S get() {
    if (myValue == null) {
      myValue = doGet();
    }
    return myValue;
  }

  public boolean isCached() {
    return myValue != null;
  }

  /**
   * Should not return null
   *
   * @return calculates the value to be cached and used.
   */
  @NotNull
  protected abstract S doGet();

  @NotNull
  public static <S> CachingValue<S> simple(@NotNull final S value) {
    return new CachingValue<S>() {
      @NotNull
      @Override
      protected S doGet() {
        return value;
      }

      @Override
      public boolean isCached() {
        return true;
      }
    };
  }

  @NotNull
  public static <S> CachingValue<S> simple(@NotNull Supplier<S> value) {
    return new CachingValue<S>() {
      @NotNull
      @Override
      protected S doGet() {
        return value.get();
      }
    };
  }
}